﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Newtonsoft.Json.Linq;

namespace WaterWay.Utilities
{
    public class WebServiceHelper
    {
        /// <summary>
        /// 根据指定的信息，调用远程WebService方法
        /// </summary>
        /// <param name="url">WebService的http形式的地址</param>
        /// <param name="methodname">欲调用的WebService的方法名</param>
        /// <param name="args">参数列表</param>
        /// <returns>WebService的执行结果</returns>
        /// <remarks>
        /// 如果调用失败，将会抛出Exception。请调用的时候，适当截获异常。
        /// 异常信息可能会发生在两个地方：
        /// 1、动态构造WebService的时候，CompileAssembly失败。
        /// 2、WebService本身执行失败。
        /// </remarks>
        /// <example>
        /// <code>
        /// object obj = InvokeWebService("http://localhost/Service.asmx","method",new object[]{"1"});
        /// </code>
        /// </example>
        public static object InvokeWebService(string url, string methodname, object[] args)
        {
            try
            {
                string @namespace = "WebService.DynamicWebCalling";
                string[] parts = url.Split('/');
                string[] pps = parts[parts.Length - 1].Split('.');
                string classname = pps[0];
                System.Net.WebClient wc = new System.Net.WebClient();
                System.IO.Stream stream = wc.OpenRead(url + "?WSDL");
                System.Web.Services.Description.ServiceDescription sd = System.Web.Services.Description.ServiceDescription.Read(stream);
                System.Web.Services.Description.ServiceDescriptionImporter sdi = new System.Web.Services.Description.ServiceDescriptionImporter();
                sdi.AddServiceDescription(sd, "", "");
                System.CodeDom.CodeNamespace cn = new System.CodeDom.CodeNamespace(@namespace);
                System.CodeDom.CodeCompileUnit ccu = new System.CodeDom.CodeCompileUnit();
                ccu.Namespaces.Add(cn);
                sdi.Import(cn, ccu);

                Microsoft.CSharp.CSharpCodeProvider csc = new Microsoft.CSharp.CSharpCodeProvider();
                System.CodeDom.Compiler.ICodeCompiler icc = csc.CreateCompiler();

                System.CodeDom.Compiler.CompilerParameters cplist = new System.CodeDom.Compiler.CompilerParameters();
                cplist.GenerateExecutable = false;
                cplist.GenerateInMemory = true;
                cplist.ReferencedAssemblies.Add("System.dll");
                cplist.ReferencedAssemblies.Add("System.XML.dll");
                cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
                cplist.ReferencedAssemblies.Add("System.Data.dll");

                System.CodeDom.Compiler.CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
                if (true == cr.Errors.HasErrors)
                {
                    System.Text.StringBuilder sb = new System.Text.StringBuilder();
                    foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)
                    {
                        sb.Append(ce.ToString());
                        sb.Append(System.Environment.NewLine);
                    }
                    throw new Exception(sb.ToString());
                }
                System.Reflection.Assembly assembly = cr.CompiledAssembly;
                Type t = assembly.GetType(@namespace + "." + classname, true, true);
                object obj = Activator.CreateInstance(t);
                System.Reflection.MethodInfo mi = t.GetMethod(methodname);
                object result = mi.Invoke(obj, args);

                //释放资源
                wc.Dispose();
                stream.Dispose();
                stream.Close();
                csc.Dispose();


                wc = null;
                stream = null;
                sd = null;
                sdi = null;
                cn = null;
                ccu = null;
                csc = null;
                icc = null;
                cplist = null;
                cr = null;
                assembly = null;
                obj = null;

                return result;
            }
            catch (Exception ex)
            {
                throw ex;
            }


        }

        /// <summary>
        /// 通过HTTPGET方法调用短信接口
        /// </summary>
        /// <param name="LSH">流水号</param>
        /// <param name="phone">发送的手机号</param>
        /// <param name="content">内容</param>
        /// <param name="partId"></param>
        public static bool InvokeWebServiceSendMsg(string LSH, string phone, string content, string partId)
        {
            string url = string.Format("{0}/{1}", ConfigHelper.AppSettings("WebServiceUrl"), "SendMessage");
            string args = string.Format("strLsh={0}&strPhone={1}&strNR={2}&strPartID={3}", LSH, phone, HttpUtility.UrlEncode(content), partId);//将短信内容转成url格式
            string result = GetByHttp(string.Format("{0}?{1}", url, args));
            JObject jObject = JObject.Parse(result);
            LogHelper.Current().LogInfo(result);//记录下WebService返回的json数据
            return jObject["isSucceed"].ToString().ToLower()=="true";
        }

        public static string HttpPost(string url, string postDataStr)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            if (postDataStr != null)
            {
                request.ContentLength = Encoding.UTF8.GetByteCount(postDataStr);
            }
            //request.CookieContainer = cookie;
            Stream myRequestStream = request.GetRequestStream();
            if (postDataStr != null)
            {
                StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.GetEncoding("gb2312"));
                myStreamWriter.Write(postDataStr);
                myStreamWriter.Flush();
                myStreamWriter.Close();
            }

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            //response.Cookies = cookie.GetCookies(response.ResponseUri);
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            string retString = myStreamReader.ReadToEnd();
            myStreamReader.Close();
            myResponseStream.Close();

            return retString;
        }



        public static string GetByHttp(string url)//, out string errormes)
        {
            //errormes = string.Empty;
            LogHelper.Current().LogInfo(url);
            System.Net.WebClient wc = new System.Net.WebClient();
            byte[] b;
            try
            {
                b = wc.DownloadData(url);
                string result = string.Empty;
                result = System.Text.Encoding.UTF8.GetString(b);
                //result = System.Text.Encoding.Default.GetString(b);
                result = result.Replace("\r", "");
                result = result.Replace("\n", "");
                result = result.Replace("<?xml version=\"1.0\" encoding=\"utf-8\"?><string xmlns=\"http://tempuri.org/\">", "");
                result = result.Replace("</string>", "");
                return result;
            }
            catch (Exception ex)
            {
                throw ex;
                //errormes = ex.Message;
                //string str = "远程服务器返回错误: (404) 未找到。";
                //string str2 = "无法连接到远程服务器。";

                //if (ex.Message.IndexOf(str) >= 0 || ex.Message.IndexOf(str2) >= 0)
                //{
                //    errormes = "短信平台webService无法连接，请检查配置文件【SmsPlatformWebServiceUrl】是否正确";
                //}
                //else
                //    throw new Exception();
                //// throw new SmsPlatFormError { mes = errormes }; ;

                //return "-1";
            }
            finally
            {
                wc.Dispose();
                wc = null;
                b = null;
            }
        }

    }
}
